package com.lemurian.bankdata.action.business;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.lemurian.bankdata.dto.LogHelper;
import com.lemurian.bankdata.lite.authentication.BankDataPrincipal;
import com.lemurian.bankdata.lite.enums.ApplicationCategory;
import com.lemurian.bankdata.lite.enums.UserActivityType;
import com.lemurian.bankdata.lite.logger.BankDataLogger;
import com.lemurian.bankdata.lite.struts.Pager;
import com.lemurian.bankdata.lite.struts.PartialList;
import com.lemurian.bankdata.lite.utils.GeneralConstant;
import com.lemurian.bankdata.lite.utils.GlobalFunction;
import com.lemurian.bankdata.services.ActivityLogService;
import com.lemurian.bankdata.services.CategoryService;
import com.lemurian.bankdata.services.CertificateService;
import com.lemurian.bankdata.utils.BaseAction;
import com.lemurian.entity.Category;
import com.lemurian.entity.Certificate;
import com.lemurian.entity.User;
import com.opensymphony.xwork2.Preparable;

public class SertifikatAction extends BaseAction implements Preparable {

	private static final long serialVersionUID = 1L;
	
	private BankDataLogger log = BankDataLogger.getLogger(SertifikatAction.class.getSimpleName());
	
	private Certificate certificate = new Certificate();
	private List<Certificate> certificates;
	
	private int sertifikatId;
	private List<Category> listSertifikat;
	
	private int remarksId;
	private List<Category> listSertifikatRemarks;
	
	private int id = 0;

	private User user;
	private BankDataPrincipal principal;
	
	@Autowired private CertificateService certificateService;
	
	@Autowired private ActivityLogService userActivityLogService;
	@Autowired private CategoryService categoryService;
	
	private LogHelper userActivityLog;

	private boolean hapus;
	
	@Override
	public void prepare() throws Exception {
		principal = (BankDataPrincipal) getSession().get(GeneralConstant.USER_PRINCIPAL);
		user = principal.getUser();
		
		log.sInfo("get certificate id [%s]", id);
        if (id > 0) {
        	certificate = certificateService.loadWithDebitur(id);
        	if (certificate != null) {
        		log.sInfo("get certificate name ", certificate.getName());	
			} else {
				log.info("certificate not found");
			}
        }
	}

	@Override
	@SkipValidation
	public String list() {
		log.info("list Certificate");
		setPreviousPage(GeneralConstant.LIST);
		
		try {
			PartialList<Certificate> partialList = certificateService.findByCriteria(getStart(), getCount(),
					getAscDesc().equalsIgnoreCase("desc") ? Order.desc(getOrderBy().length() > 0 ? getOrderBy() : "name") : Order.asc(getOrderBy().length() > 0 ? getOrderBy() : "name"),
                    certificate.getName() != null && certificate.getName().length() > 0 ? Restrictions.ilike("name", certificate.getName(), MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1)),
                    certificate.getNumber() != null && certificate.getNumber().length() > 0 ? Restrictions.ilike("number", certificate.getNumber(), MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1))
                    );

            certificates = partialList.getList();
            log.sInfo("found [%s] certificates", certificates.size());

            setPager(Pager.generatePager(getStart(), getCount(), partialList.getTotal()));
            setPagerItem(Pager.generatePagerItem(getStart(), getCount(), partialList.getTotal()));

            partialList = null;

		} catch (Exception e) {
			e.printStackTrace();
		}
        setMappedRequest(GeneralConstant.LIST);
        return SUCCESS;
	}

	@Override
	@SkipValidation
	public String add() {
		log.info("on add certificate page ..");

		getSession().put(GeneralConstant.TIME_IN_SESSION, new Date());
		
	    setMappedRequest(GeneralConstant.SAVE);
	    setPreviousPage(GeneralConstant.ADD);
	    
	    listSertifikat = categoryService.findByCriteria(Order.asc("id"),(Restrictions.eq("parent.id", ApplicationCategory.SERTIFIKAT.code())));
    	log.sInfo("found listSertifikat [%s]", listSertifikat.size());
    	
    	listSertifikatRemarks = categoryService.findByCriteria(Order.asc("id"),(Restrictions.eq("parent.id", ApplicationCategory.KETERANGAN_SERTIFIKAT.code())));
    	log.sInfo("found listSertifikatRemarks [%s]", listSertifikatRemarks.size());
    	
    	if (certificate.getType() != null) {
			sertifikatId = certificate.getType().getId();
			log.sInfo("Get certificate type ID [%s]", sertifikatId);
		}
    	
    	if (certificate.getRemarks() != null) {
    		remarksId = certificate.getRemarks().getId();
			log.sInfo("Get certificate remarks ID [%s]", remarksId);
		}
	    
	    return SUCCESS;
	}

	@Override
	public String save() {
		if(certificate.getName() == null || certificate.getName().equalsIgnoreCase("")) {
            addCustomActionError("Masukkan Nama yang tercantum di Sertifikat");
        }

        if(certificate.getNumber() == null || certificate.getNumber().equalsIgnoreCase("")) {
        	addCustomActionError("Masukkan Nomor Sertifikat");
        }
		
		String message = "";
		try {
			if (sertifikatId > 0) {
				Category certificateType = categoryService.findById(sertifikatId);
				log.info("got certificate : " + certificateType.getName());
				certificate.setType(certificateType);	
			}
			
			log.info("remarks id : " + remarksId);
			if (remarksId > 0) {
				Category remarks = categoryService.findById(remarksId);
				log.info("got remarks : " + remarks.getName());
				certificate.setRemarks(remarks);	
			}
			
			if(getId() > 0) {
				certificate.setUpdateBy(user.getLoginId());
				certificate.setUpdateDate(new Timestamp(System.currentTimeMillis()));
			} else {
				certificate.setCreateBy(user.getLoginId());
				certificate.setCreateDate(new Timestamp(System.currentTimeMillis()));
			}
			
			if (hapus) {
				certificate.setClient(null);
			}
			
			log.sInfo("Start saving certificate for [%s].. ", certificate.getName());
			certificateService.save(certificate);
			
			if(getId() > 0) {
				message = "Update";
                userActivityLog = new LogHelper(user, UserActivityType.UPDATE_CERTIFICATE);
            } else {
            	message = "Add";
                userActivityLog = new LogHelper(user, UserActivityType.ADD_CERTIFICATE);
            }
			
			try {
                message += " " + certificate.getName() + " is success";

                log.sInfo(" :: User [%s:%s] is successfully save Certificate [%s:%s]", user.getId(), user.getName(), certificate.getId(), certificate.getName());
                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);

                addCustomActionMessage(message);
            } catch (Exception e) {
                message += " " + certificate.getName() + " is failed, message : "+e.getMessage();

                //set activity log status into failed
                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
                userActivityLog.setErrorMsg(e.getMessage());
                addCustomActionError(message);
            }
            
            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
            userActivityLog.setStartDate((Date) getSession().get(GeneralConstant.TIME_IN_SESSION));
            userActivityLog.getAdditionalParams().add(certificate.getName());
            userActivityLogService.saveUserActivity(userActivityLog);
            getSession().remove(GeneralConstant.TIME_IN_SESSION);
			
		} catch (Throwable t) {
            t.printStackTrace();
            log.info("Error save : " + t.getMessage());
        }
		
		setMappedRequestFullPath("SertifikatAction_list.do");
		return GeneralConstant.REDIRECT;

	}

	@Override
	@SkipValidation
	public String edit() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String update() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SkipValidation
	public String detail() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SkipValidation
	public String delete() {

		try {
			certificateService.delete(certificate);
			
			userActivityLog = new LogHelper(user, UserActivityType.DELETE_CERTIFICATE);
			
			String message = "";
            try {
                message = "Delete " + certificate.getName() + " is success";
                addActionMessage(message);
                log.sInfo(" :: User [%s:%s] is successfully delete certificate [%s:%s]", user.getId(), user.getName(), certificate.getId(), certificate.getName());

                //check if activity is success
                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
            } catch (Exception e) {
                message = "Delete " + certificate.getName() + " is failed, message : "+e.getMessage();
                addActionError(message);
                log.sInfo(" :: Error was raised when User [%s:%s] delete certificate [%s:%s]", user.getId(), user.getName(), certificate.getId(), certificate.getName());
                
                //set activity log status into failed
                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
                userActivityLog.setErrorMsg(e.getMessage());
            }
            //save activity log
            userActivityLog.getAdditionalParams().add(certificate.getName());
            userActivityLogService.saveUserActivity(userActivityLog);
            
		} catch (Throwable t) {
			addCustomActionError(t.getMessage());
			t.printStackTrace();
		}
		setMappedRequestFullPath("SertifikatAction_list.do");
		return GeneralConstant.REDIRECT;
	}

	// ==========================================================================================================================================
	// GETTER SETTER

	public Certificate getCertificate() {
		return certificate;
	}

	public void setCertificate(Certificate certificate) {
		this.certificate = certificate;
	}

	public List<Certificate> getCertificates() {
		return certificates;
	}

	public void setCertificates(List<Certificate> certificates) {
		this.certificates = certificates;
	}

	public int getId() {
		return id;
	}

	public void setId(String id) {
		int id_ = 0;
		if(id != null && !id.equalsIgnoreCase("0")) {
			id = GlobalFunction.decodeParameter(id);
	        id_ = Integer.parseInt(id);
		}
        this.id = id_;
	}

	public List<Category> getListSertifikat() {
		return listSertifikat;
	}

	public void setListSertifikat(List<Category> listSertifikat) {
		this.listSertifikat = listSertifikat;
	}

	public int getSertifikatId() {
		return sertifikatId;
	}

	public void setSertifikatId(String sertifikatId) {
		int id_ = 0;
		if(sertifikatId != null && !sertifikatId.equalsIgnoreCase("0")) {
			sertifikatId = GlobalFunction.decodeParameter(sertifikatId);
	        id_ = Integer.parseInt(sertifikatId);
		}
        this.sertifikatId = id_;
	}

	public int getRemarksId() {
		return remarksId;
	}

	public void setRemarksId(String remarksId) {
		int id_ = 0;
		if(remarksId != null && !remarksId.equalsIgnoreCase("0")) {
			remarksId = GlobalFunction.decodeParameter(remarksId);
	        id_ = Integer.parseInt(remarksId);
		}
        this.remarksId = id_;
	}

	public List<Category> getListSertifikatRemarks() {
		return listSertifikatRemarks;
	}

	public void setListSertifikatRemarks(List<Category> listSertifikatRemarks) {
		this.listSertifikatRemarks = listSertifikatRemarks;
	}

	public boolean isHapus() {
		return hapus;
	}

	public void setHapus(boolean hapus) {
		this.hapus = hapus;
	}
		

}
